package ro.upt.ac.cstaicu.ui;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;

import ro.upt.ac.cstaicu.FaultLocalizationTechniques;
import ro.upt.ac.cstaicu.TestFrameworks;
import ro.upt.ac.cstaicu.analyze.Entity;
import ro.upt.ac.cstaicu.analyze.FaultLocalisationTechnique;
import ro.upt.ac.cstaicu.analyze.JaccardTechnique;
import ro.upt.ac.cstaicu.analyze.TarantulaTechnique;
import ro.upt.ac.cstaicu.execution.CachedClassFilesManager;
import ro.upt.ac.cstaicu.execution.Executor;
import ro.upt.ac.cstaicu.execution.TestResult;
import ro.upt.ac.cstaicu.execution.junit.JunitFacade;
import ro.upt.ac.cstaicu.execution.testng.TestNGFacade;
import ro.upt.ac.cstaicu.instrumentation.InstrumentationFacade;
import ro.upt.ac.cstaicu.instrumentation.Instrumentor;
import ro.upt.ac.cstaicu.instrumentation.logging.GlobalLogger;
import ro.upt.ac.cstaicu.instrumentation.logging.PredicateCounterLogger;

/**
 * A client class that put all the other packages together.
 * 
 * @author Cristian-Alexandru STAICU
 * 
 */
public class EclipseConnector {

	private static String pathToProjectSourceCode;
	private static Collection<Entity> lastLoggedEntities;
	private static ArrayList<TestResult> lastTestResults;
	private static FaultLocalisationTechnique fl = null;
	
	/**
	 * 
	 * @return path to the current project
	 */
	public static String getPathToSourceCode() {
		return pathToProjectSourceCode;
	}
	
	public static SherlockJResult findBugs(File[] classPathEntries, String pathToProject, String pathToBinaries, Collection<String> testClasses, Collection<String> ignoredTests, TestFrameworks testFramework, FaultLocalizationTechniques flt) {
		
//		System.out.println(pathToProject + " " + pathToBinaries);
		Instrumentor instrumentationModule = new InstrumentationFacade();
		
//		HashMap<String, ArrayList<Predicate>> predicates = instrumentationModule
//			.tracePredicatesFromClass(pathToBinaries, "test.Example");
//		System.out.println(predicates);
		
		GlobalLogger logger = PredicateCounterLogger.getInstance();
		logger.clearPredicates();
	
		
//		logger.setPredicates(predicates);
		logger.startLogging(pathToProject + "out.sj");
		
		Executor executeModule;
		if (testFramework == TestFrameworks.JUnit)
			executeModule = new JunitFacade(instrumentationModule, logger, ignoredTests);
		else 
			executeModule = new TestNGFacade(instrumentationModule, logger, ignoredTests);
		
		for (String testClass : testClasses) {
			executeModule.executeTestClass(classPathEntries, pathToBinaries, testClass);
		}
		
		lastTestResults = executeModule.getTestResults();
		lastLoggedEntities = logger.endLogging();
		
		if (flt == FaultLocalizationTechniques.Jaccard)
			fl = new JaccardTechnique();
		if (flt == FaultLocalizationTechniques.Tarantula)
			fl = new TarantulaTechnique();
		
//		for (Entity e : lastLoggedEntities) {
//			System.out.println(e.context.getId());
//		}
		executeModule.clean();
		CachedClassFilesManager.clearHistory();
		return new SherlockJResult(fl.rankEntities(lastLoggedEntities, logger.getResults()),
				executeModule.getTestResults());
	}
	
	public static SherlockJResult recomputePredictions(TestResult test) {
		return new SherlockJResult(fl.rankSingleErrorEntities(lastLoggedEntities, lastTestResults, test), lastTestResults);
		
	}
	
}
